iT邦幫忙

2022 iThome 鐵人賽

DAY 29
1
Mobile Development

從開發瀏覽器 APP 學習 Android 實戰技巧,並搭上 Jetpack Compose 的列車系列 第 30

[Day29] 從開發瀏覽器 APP 學習實戰技巧 -- 追蹤碼退散!享受不受監視的瀏覽體驗

  • 分享至 

  • xImage
  •  

前一陣子看到新版 Firefox 102 版開始,可以讓使用者決定是不是要把網址中的一些 query parameters 過濾掉,常見的像是 facebook 的 id 追蹤 fbclid,還有 Google 的 ga_*, gclid 等;還有在追蹤活動時很常用的 utm_* 系列。如果這些足跡能在瀏覽網頁時去除掉,對於自己的隱私可以多一層保障。

所以,我也打算在 EinkBro 中來實作一下。這個功能主要可以分成兩部份:第一部份是取得哪些是應該要過濾掉的 query parameters,將它們用適當的方式儲存下來;第二部份才是透過跟網址比對,決定哪些參數需要清除,哪些是正常的,需要保留下來。

一開始,並沒有找到 Firefox 的實作方式,所以先在 Github 上找了其他 Open Source 的 repository 來參考。第一步是先將這個 Neat-URL 的資料納為己用。它的資料中已經有列了很多常見網站的各種追蹤參數;有些是可以套在所有網站上的,有些是特定網站才會冒出來的參數。我先將這份 json 檔案存到了程式中,並且在 EinkBro 一開始執行的時候,就把下面的 params 存到了一個 List 中。每次要載入 url 時,都會去跟這些 params 做比較,如果有符合格式的話,就將其排除。

裡頭的資料大概長這樣:

{
    "categories": [
        { "name": "Amazon", "params": ["_encoding@amazon.*", "ascsubtag@amazon.*", "pd_rd_*@amazon.*", "pf@amazon.*", "pf_rd_*@amazon.*", "psc@amazon.*", "ref_@amazon.*", "tag@amazon.*"]},
        { "name": "Bilibili.com", "params": ["callback@bilibili.com"]},
        { "name": "Bing", "params": ["cvid@bing.com", "form@bing.com", "pq@bing.com", "qs@bing.com", "sc@bing.com", "sk@bing.com", "sp@bing.com"]},
        { "name": "Campaign tracking (Adobe Analytics)", "params": ["sc_cid"]},
        { "name": "Campaign tracking (Google Analytics, ga)", "params": ["ga_*", "gclid", "gclsrc"]},
        { "name": "Facebook", "params": ["fb_action_ids", "fb_action_types", "fb_ref", "fb_source", "fbclid", "hrc@facebook.com", "refsrc@facebook.com"]},
        { "name": "Google", "params": ["ei@google.*", "gs_gbg@google.*", "gs_l", "gs_lcp@google.*", "gs_mss@google.*", "gs_rn@google.*", "gws_rd@google.*", "sei@google.*", "ved@google.*"]},

        { "name": "LinkedIn", "params": ["eBP@linkedin.com", "lgCta@linkedin.com", "lgTemp@linkedin.com", "lipi@linkedin.com", "midSig@linkedin.com", "midToken@linkedin.com", "recommendedFlavor@linkedin.com", "refId@linkedin.com", "trackingId@linkedin.com", "trk@linkedin.com", "trkEmail@linkedin.com"]},
        { "name": "Medium", "params": ["_branch_match_id@medium.com", "source@medium.com"]},
        { "name": "TikTok", "params": ["_d@tiktok.com", "checksum@tiktok.com", "is_copy_url@tiktok.com", "is_from_webapp@tiktok.com", "language@tiktok.com", "preview_pb@tiktok.com", "sec_user_id@tiktok.com", "sender_device@tiktok.com", "sender_web_id@tiktok.com", "share_app_id@tiktok.com", "share_link_id@tiktok.com", "share_item_id@tiktok.com", "source@tiktok.com", "timestamp@tiktok.com", "tt_from@tiktok.com", "u_code@tiktok.com", "user_id@tiktok.com"]},
        { "name": "Twitch.tv", "params": ["tt_content", "tt_medium"]},
        { "name": "Twitter", "params": ["cxt@*.twitter.com", "ref_*@*.twitter.com", "s@*.twitter.com", "t@*.twitter.com", "twclid"]},
    ]
}

目前判斷的邏輯還沒全部完成,但至少通用型的參數,目前都可以過濾掉了。實做方式大致如下:

https://ithelp.ithome.com.tw/upload/images/20221011/20140260kCyfpb7DJb.png

有了個別的參數比對函式後,再來是將 url string 分解成 Uri ,將裡頭的 query parameters 一個個拿出來做比較:

https://ithelp.ithome.com.tw/upload/images/20221011/20140260QIXyFyayov.png

完成後,再來就是把會用到網址的地方加上上述的邏輯。主要有兩個地方,一個是在 loadUrl 時,這時候的 url 有可能是使用者從外部其他 App 帶進來的,我不想讓它在 EinkBro 發出網頁 request 時順便也送出這些參數;所以在 loadUrl 時,可以做這個處理。

時機

另一個地方是,在 EinkBro 中,要把當下網站的某些網頁連結分享到別的 App 去時;這時候網站給出來的網頁連結也有可能是塞滿追蹤碼的。為了讓其他 App 不要也拿到被追蹤的連結,在這個時間點也可以先處理過再把連結傳送出去。

結論

少了一堆追蹤碼後,心裡就更踏實了!

不過,要注意一點是:有時有些網站(像是購物網站)的活動會利用上面講的某些 query parameters 來記錄,如果全部都濾掉的話,反而會被認為是沒有符合規定的使用者。所以,我在 EinkBro 設定頁面裡增加了一個選項,讓使用者可以自己開關"過濾追蹤碼"的功能,而且預設是關閉的,避免影響到不知情的使用者的使用場景。

Firefox 的實作

在套用 Neat-Url 的作法時,我還是繼續想要找出 Firefox 的實作方式。原先以為它會是用 Android 的 kotlin 撰寫的,結果發現我的尋找方向錯誤:這功能實際上是用 C++ 開發的。連結在此

Brave Browser 的實作

另外,也意外地找到了 Brave Browser 中的實作方式。但是,Brave Browser 的實作方式比較陽春就是了。,它會處理的資料如下:

static constexpr auto kSimpleQueryStringTrackers =
    base::MakeFixedFlatSet<base::StringPiece>(
        {// https://github.com/brave/brave-browser/issues/4239
         "fbclid", "gclid", "msclkid", "mc_eid",
         // https://github.com/brave/brave-browser/issues/9879
         "dclid",
         // https://github.com/brave/brave-browser/issues/13644
         "oly_anon_id", "oly_enc_id",
         // https://github.com/brave/brave-browser/issues/11579
         "_openstat",
         // https://github.com/brave/brave-browser/issues/11817
         "vero_conv", "vero_id",
         // https://github.com/brave/brave-browser/issues/13647
         "wickedid",
         // https://github.com/brave/brave-browser/issues/11578
         "yclid",
         // https://github.com/brave/brave-browser/issues/8975
         "__s",
         // https://github.com/brave/brave-browser/issues/17451
         "rb_clickid",
         // https://github.com/brave/brave-browser/issues/17452
         "s_cid",
         // https://github.com/brave/brave-browser/issues/17507
         "ml_subscriber", "ml_subscriber_hash",
         // https://github.com/brave/brave-browser/issues/18020
         "twclid",
         // https://github.com/brave/brave-browser/issues/18758
         "gbraid", "wbraid",
         // https://github.com/brave/brave-browser/issues/9019
         "_hsenc", "__hssc", "__hstc", "__hsfp", "hsCtaTracking",
         // https://github.com/brave/brave-browser/issues/22082
         "oft_id", "oft_k", "oft_lk", "oft_d", "oft_c", "oft_ck", "oft_ids",
         "oft_sk",
         // https://github.com/brave/brave-browser/issues/24988
         "ss_email_id",
         // https://github.com/brave/brave-browser/issues/25238
         "bsft_uid", "bsft_clkid",
         // https://github.com/brave/brave-browser/issues/11580
         "igshid"});

相關連結 (commits)


上一篇
[Day28] 從開發瀏覽器 APP 學習實戰技巧 -- 是時候淘汰 onActivityResult 了
下一篇
[Day30] 從開發瀏覽器 APP 學習實戰技巧 -- 總結 & SharedPreferences
系列文
從開發瀏覽器 APP 學習 Android 實戰技巧,並搭上 Jetpack Compose 的列車31
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言